package com.fr.base.core.antlr.collections.impl;

import com.fr.base.core.antlr.CharFormatter;

public class BitSet
  implements Cloneable
{
  protected static final int BITS = 64;
  protected static final int NIBBLE = 4;
  protected static final int LOG_BITS = 6;
  protected static final int MOD_MASK = 63;
  protected long[] bits;

  public BitSet()
  {
    this(64);
  }

  public BitSet(long[] paramArrayOfLong)
  {
    this.bits = paramArrayOfLong;
  }

  public BitSet(int paramInt)
  {
    this.bits = new long[(paramInt - 1 >> 6) + 1];
  }

  public void add(int paramInt)
  {
    int i = wordNumber(paramInt);
    if (i >= this.bits.length)
      growToInclude(paramInt);
    this.bits[i] |= bitMask(paramInt);
  }

  public BitSet and(BitSet paramBitSet)
  {
    BitSet localBitSet = (BitSet)clone();
    localBitSet.andInPlace(paramBitSet);
    return localBitSet;
  }

  public void andInPlace(BitSet paramBitSet)
  {
    int i = Math.min(this.bits.length, paramBitSet.bits.length);
    for (int j = i - 1; j >= 0; --j)
      this.bits[j] &= paramBitSet.bits[j];
    for (j = i; j < this.bits.length; ++j)
      this.bits[j] = 0L;
  }

  private static final long bitMask(int paramInt)
  {
    int i = paramInt & 0x3F;
    return (1L << i);
  }

  public void clear()
  {
    for (int i = this.bits.length - 1; i >= 0; --i)
      this.bits[i] = 0L;
  }

  public void clear(int paramInt)
  {
    int i = wordNumber(paramInt);
    if (i >= this.bits.length)
      growToInclude(paramInt);
    this.bits[i] &= (bitMask(paramInt) ^ 0xFFFFFFFF);
  }

  public Object clone()
  {
    BitSet localBitSet;
    try
    {
      localBitSet = (BitSet)super.clone();
      localBitSet.bits = new long[this.bits.length];
      System.arraycopy(this.bits, 0, localBitSet.bits, 0, this.bits.length);
    }
    catch (CloneNotSupportedException localCloneNotSupportedException)
    {
      throw new InternalError();
    }
    return localBitSet;
  }

  public int degree()
  {
    int i = 0;
    for (int j = this.bits.length - 1; j >= 0; --j)
    {
      int k;
      long l = this.bits[j];
      if (l != 0L)
        for (k = 63; k >= 0; --k)
          if ((l & 1L << k) != 0L)
            ++i;
    }
    return i;
  }

  public boolean equals(Object paramObject)
  {
    if ((paramObject != null) && (paramObject instanceof BitSet))
    {
      BitSet localBitSet = (BitSet)paramObject;
      int i = Math.min(this.bits.length, localBitSet.bits.length);
      int j = i;
      do
        if (j-- <= 0)
          break label63;
      while (this.bits[j] == localBitSet.bits[j]);
      return false;
      if (this.bits.length > i)
      {
        label63: j = this.bits.length;
        do
          if (j-- <= i)
            break label145;
        while (this.bits[j] == 0L);
        return false;
      }
      if (localBitSet.bits.length > i)
      {
        j = localBitSet.bits.length;
        do
          if (j-- <= i)
            break label145;
        while (localBitSet.bits[j] == 0L);
        return false;
      }
      label145: return true;
    }
    return false;
  }

  public static Vector getRanges(int[] paramArrayOfInt)
  {
    if (paramArrayOfInt.length == 0)
      return null;
    int i = paramArrayOfInt[0];
    int j = paramArrayOfInt[(paramArrayOfInt.length - 1)];
    if (paramArrayOfInt.length <= 2)
      return null;
    Vector localVector = new Vector(5);
    for (int k = 0; k < paramArrayOfInt.length - 2; ++k)
    {
      int l = paramArrayOfInt.length - 1;
      for (int i1 = k + 1; i1 < paramArrayOfInt.length; ++i1)
        if (paramArrayOfInt[i1] != paramArrayOfInt[(i1 - 1)] + 1)
        {
          l = i1 - 1;
          break;
        }
      if (l - k > 2)
        localVector.appendElement(new IntRange(paramArrayOfInt[k], paramArrayOfInt[l]));
    }
    return localVector;
  }

  public void growToInclude(int paramInt)
  {
    int i = Math.max(this.bits.length << 1, numWordsToHold(paramInt));
    long[] arrayOfLong = new long[i];
    System.arraycopy(this.bits, 0, arrayOfLong, 0, this.bits.length);
    this.bits = arrayOfLong;
  }

  public boolean member(int paramInt)
  {
    int i = wordNumber(paramInt);
    if (i >= this.bits.length)
      return false;
    return ((this.bits[i] & bitMask(paramInt)) != 0L);
  }

  public boolean nil()
  {
    for (int i = this.bits.length - 1; i >= 0; --i)
      if (this.bits[i] != 0L)
        return false;
    return true;
  }

  public BitSet not()
  {
    BitSet localBitSet = (BitSet)clone();
    localBitSet.notInPlace();
    return localBitSet;
  }

  public void notInPlace()
  {
    for (int i = this.bits.length - 1; i >= 0; --i)
      this.bits[i] ^= -1L;
  }

  public void notInPlace(int paramInt)
  {
    notInPlace(0, paramInt);
  }

  public void notInPlace(int paramInt1, int paramInt2)
  {
    growToInclude(paramInt2);
    for (int i = paramInt1; i <= paramInt2; ++i)
    {
      int j = wordNumber(i);
      this.bits[j] ^= bitMask(i);
    }
  }

  private final int numWordsToHold(int paramInt)
  {
    return ((paramInt >> 6) + 1);
  }

  public static BitSet of(int paramInt)
  {
    BitSet localBitSet = new BitSet(paramInt + 1);
    localBitSet.add(paramInt);
    return localBitSet;
  }

  public BitSet or(BitSet paramBitSet)
  {
    BitSet localBitSet = (BitSet)clone();
    localBitSet.orInPlace(paramBitSet);
    return localBitSet;
  }

  public void orInPlace(BitSet paramBitSet)
  {
    if (paramBitSet.bits.length > this.bits.length)
      setSize(paramBitSet.bits.length);
    int i = Math.min(this.bits.length, paramBitSet.bits.length);
    for (int j = i - 1; j >= 0; --j)
      this.bits[j] |= paramBitSet.bits[j];
  }

  public void remove(int paramInt)
  {
    int i = wordNumber(paramInt);
    if (i >= this.bits.length)
      growToInclude(paramInt);
    this.bits[i] &= (bitMask(paramInt) ^ 0xFFFFFFFF);
  }

  private void setSize(int paramInt)
  {
    long[] arrayOfLong = new long[paramInt];
    int i = Math.min(paramInt, this.bits.length);
    System.arraycopy(this.bits, 0, arrayOfLong, 0, i);
    this.bits = arrayOfLong;
  }

  public int size()
  {
    return (this.bits.length << 6);
  }

  public int lengthInLongWords()
  {
    return this.bits.length;
  }

  public boolean subset(BitSet paramBitSet)
  {
    if ((paramBitSet == null) || (!(paramBitSet instanceof BitSet)))
      return false;
    return and(paramBitSet).equals(this);
  }

  public void subtractInPlace(BitSet paramBitSet)
  {
    if (paramBitSet == null)
      return;
    for (int i = 0; (i < this.bits.length) && (i < paramBitSet.bits.length); ++i)
      this.bits[i] &= (paramBitSet.bits[i] ^ 0xFFFFFFFF);
  }

  public int[] toArray()
  {
    int[] arrayOfInt = new int[degree()];
    int i = 0;
    for (int j = 0; j < this.bits.length << 6; ++j)
      if (member(j))
        arrayOfInt[(i++)] = j;
    return arrayOfInt;
  }

  public long[] toPackedArray()
  {
    return this.bits;
  }

  public String toString()
  {
    return toString(",");
  }

  public String toString(String paramString)
  {
    String str = "";
    for (int i = 0; i < this.bits.length << 6; ++i)
      if (member(i))
      {
        if (str.length() > 0)
          str = str + paramString;
        str = str + i;
      }
    return str;
  }

  public String toString(String paramString, CharFormatter paramCharFormatter)
  {
    String str = "";
    for (int i = 0; i < this.bits.length << 6; ++i)
      if (member(i))
      {
        if (str.length() > 0)
          str = str + paramString;
        str = str + paramCharFormatter.literalChar(i);
      }
    return str;
  }

  public String toString(String paramString, Vector paramVector)
  {
    if (paramVector == null)
      return toString(paramString);
    String str = "";
    for (int i = 0; i < this.bits.length << 6; ++i)
      if (member(i))
      {
        if (str.length() > 0)
          str = str + paramString;
        if (i >= paramVector.size())
          str = str + "<bad element " + i + ">";
        else if (paramVector.elementAt(i) == null)
          str = str + "<" + i + ">";
        else
          str = str + ((String)paramVector.elementAt(i));
      }
    return str;
  }

  public String toStringOfHalfWords()
  {
    String str = new String();
    for (int i = 0; i < this.bits.length; ++i)
    {
      if (i != 0)
        str = str + ", ";
      long l = this.bits[i];
      l &= 4294967295L;
      str = str + l + "UL";
      str = str + ", ";
      l = this.bits[i] >>> 32;
      l &= 4294967295L;
      str = str + l + "UL";
    }
    return str;
  }

  public String toStringOfWords()
  {
    String str = new String();
    for (int i = 0; i < this.bits.length; ++i)
    {
      if (i != 0)
        str = str + ", ";
      str = str + this.bits[i] + "L";
    }
    return str;
  }

  public String toStringWithRanges(String paramString, CharFormatter paramCharFormatter)
  {
    String str = "";
    int[] arrayOfInt = toArray();
    if (arrayOfInt.length == 0)
      return "";
    for (int i = 0; i < arrayOfInt.length; ++i)
    {
      int j = 0;
      for (int k = i + 1; k < arrayOfInt.length; ++k)
      {
        if (arrayOfInt[k] != arrayOfInt[(k - 1)] + 1)
          break;
        j = k;
      }
      if (str.length() > 0)
        str = str + paramString;
      if (j - i >= 2)
      {
        str = str + paramCharFormatter.literalChar(arrayOfInt[i]);
        str = str + "..";
        str = str + paramCharFormatter.literalChar(arrayOfInt[j]);
        i = j;
      }
      else
      {
        str = str + paramCharFormatter.literalChar(arrayOfInt[i]);
      }
    }
    return str;
  }

  private static final int wordNumber(int paramInt)
  {
    return (paramInt >> 6);
  }
}